/*
FILE_URL": "http://192.168.2.73:85/upload/accessory/201511/20151114135046576869.chm",    Android Asynchronous Http Client Sample
    Copyright (c) 2014 Marek Sebera <marek.sebera@gmail.com>
    http://loopj.com

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
 */

package com.isunland.managesystem.utils;

import android.annotation.SuppressLint;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.provider.MediaStore.Audio;
import android.text.TextUtils;
import com.isunland.managesystem.R;
import com.isunland.managesystem.common.MyApplication;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Comparator;

// Source: http://stackoverflow.com/questions/12910503/android-read-file-as-string
@SuppressWarnings("all") public class FileUtil {

  private static final String[][] MIME_MapTable = {
      // {后缀名，MIME类型}
      { ".3gp", "video/3gpp" }, { ".apk", "application/vnd.android.package-archive" },
      { ".asf", "video/x-ms-asf" }, { ".avi", "video/x-msvideo" },
      { ".bin", "application/octet-stream" }, { ".bmp", "image/bmp" }, { ".c", "text/plain" },
      { ".class", "application/octet-stream" }, { ".conf", "text/plain" }, { ".cpp", "text/plain" },
      { ".doc", "application/msword" }, {
      ".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
  }, { ".xls", "application/vnd.ms-excel" }, {
      ".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
  }, { ".exe", "application/octet-stream" }, { ".gif", "image/gif" },
      { ".gtar", "application/x-gtar" }, { ".gz", "application/x-gzip" }, { ".h", "text/plain" },
      { ".htm", "text/html" }, { ".html", "text/html" }, { ".jar", "application/java-archive" },
      { ".java", "text/plain" }, { ".jpeg", "image/jpeg" }, { ".jpg", "image/jpeg" },
      { ".js", "application/x-javascript" }, { ".log", "text/plain" },
      { ".m3u", "audio/x-mpegurl" }, { ".m4a", "audio/mp4a-latm" }, { ".m4b", "audio/mp4a-latm" },
      { ".m4p", "audio/mp4a-latm" }, { ".m4u", "video/vnd.mpegurl" }, { ".m4v", "video/x-m4v" },
      { ".mov", "video/quicktime" }, { ".mp2", "audio/x-mpeg" }, { ".mp3", "audio/x-mpeg" },
      { ".mp4", "video/mp4" }, { ".mpc", "application/vnd.mpohun.certificate" },
      { ".mpe", "video/mpeg" }, { ".mpeg", "video/mpeg" }, { ".mpg", "video/mpeg" },
      { ".mpg4", "video/mp4" }, { ".mpga", "audio/mpeg" }, { ".msg", "application/vnd.ms-outlook" },
      { ".ogg", "audio/ogg" }, { ".pdf", "application/pdf" }, { ".png", "image/png" },
      { ".pps", "application/vnd.ms-powerpoint" }, { ".ppt", "application/vnd.ms-powerpoint" }, {
      ".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"
  }, { ".prop", "text/plain" }, { ".rc", "text/plain" }, { ".rmvb", "audio/x-pn-realaudio" },
      { ".rtf", "application/rtf" }, { ".sh", "text/plain" }, { ".tar", "application/x-tar" },
      { ".tgz", "application/x-compressed" }, { ".txt", "text/plain" }, { ".wav", "audio/x-wav" },
      { ".wma", "audio/x-ms-wma" }, { ".wmv", "audio/x-ms-wmv" },
      { ".wps", "application/vnd.ms-works" }, { ".xml", "text/plain" },
      { ".z", "application/x-compress" }, { ".zip", "application/x-zip-compressed" }, { "", "*/*" }
  };

  public static String convertStreamToString(InputStream is) throws Exception {
    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    StringBuilder sb = new StringBuilder();
    String line;
    while ((line = reader.readLine()) != null) {
      sb.append(line).append("\n");
    }
    return sb.toString();
  }

  public static String getStringFromFile(File file) throws Exception {
    FileInputStream fin = new FileInputStream(file);
    String ret = convertStreamToString(fin);
    // Make sure you close all streams.
    fin.close();
    return ret;
  }

  /**
   * 重命名文件,返回新的文件路径.
   * 如果范围文件路径为空,说明重命名失败.
   *
   * @param filePathAndName 文件全路径名.
   * @return 新的文件路径.
   */
  public static String renameFile(String filePathAndName) {
    if (TextUtils.isEmpty(filePathAndName)) {
      return null;
    }
    String oldName = "";
    String filePath = "";
    String newName = "";
    try {
      oldName = FileUtil.getFileNameByFilePath(filePathAndName);
      filePath = filePathAndName.substring(0, filePathAndName.lastIndexOf("/"));
    } catch (Exception e) {
      LogUtil.e("error", e);
      return null;
    }
    newName = oldName.substring(0, oldName.lastIndexOf(".")) + "_" + oldName.substring(
        oldName.lastIndexOf("."), oldName.length());
    LogUtil.i("oldName=" + oldName + ",newname=" + newName + ",filePath=" + filePath);
    renameFile(filePath, oldName, newName);
    return filePath + "/" + newName;
  }

  /**
   * 文件重命名
   *
   * @param path 文件目录
   * @param oldname 原来的文件名
   * @param newname 新文件名
   */
  public static void renameFile(String path, String oldname, String newname) {
    if (!oldname.equals(newname)) {// 新的文件名和以前文件名不同时,才有必要进行重命名
      File oldfile = new File(path + "/" + oldname);
      File newfile = new File(path + "/" + newname);
      if (!oldfile.exists()) {
        LogUtil.e("文件不存在！");
        return;// 重命名文件不存在
      }
      if (newfile.exists())// 若在该目录下已经有一个文件和新文件名相同，则不允许重命名
      {
        LogUtil.e(newname + "已经存在！");
      } else {
        oldfile.renameTo(newfile);
      }
    } else {
      LogUtil.e("新文件名和旧文件名相同...");
    }
  }

  /**
   * 获取缓存目录.
   */
  public static String getCacheDir() {

    //String filePathString = Environment.getExternalStorageDirectory()
    //		+ "/Android/data/com.isunland.managesystem/file/cache";
    //File file = new File(filePathString);
    //if (!file.exists()) {
    //	file.mkdirs();
    //}

    StringBuilder sb = new StringBuilder();
    File filePath = null;
    if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())
        || !Environment.isExternalStorageRemovable()) {
      filePath = MyApplication.getAppContext().getExternalCacheDir();
    } else {
      filePath = MyApplication.getAppContext().getCacheDir();
    }

    //某些机型上，getExternalCacheDir方法会返回空，这时候需要手动拼接路径。
    if (filePath != null) {
      sb.append(filePath.getAbsolutePath());
    } else {
      sb.append(Environment.getExternalStorageDirectory().getPath())
          .append("/Android/data/")
          .append(MyApplication.getAppContext().getPackageName())
          .append("/cache");
    }

    LogUtil.i("缓存文件目录:" + sb.toString());
    return sb.toString();
  }

  /**
   * 获取外部存储目录.
   */
  public static String getExternalDir() {
    String path = Environment.getExternalStorageDirectory().getPath() + "/guoxinerp";

    //如果目录不存在,创建目录.
    File file = new File(path);
    if ((file != null) && (!file.exists())) {
      file.mkdirs();
    }
    return path;
  }

  /**
   * 获取日志目录
   */
  public static String getLogDir() {
    return getCacheDir() + "/log";
  }

  /**
   * 获取临时文件目录
   */
  public static String getFileDir() {
    return getCacheDir() + "/file";
  }

  public static String getPathFromUri(Context context, Uri data) {

    String filename = "";
    if (data.getScheme().toString().compareTo("content") == 0) {
      Cursor cursor = context.getContentResolver()
          .query(data, new String[] { Audio.Media.DATA }, null, null, null);
      if (cursor.moveToFirst()) {
        filename = cursor.getString(0);
      }
    } else if (data.getScheme().toString().compareTo("file") == 0) // file:///开头的uri
    {
      filename = data.toString();
      filename = data.toString().replace("file://", "");
      // 替换file://
      if (!filename.startsWith("/mnt")) {
        // 加上"/mnt"头
        filename += "/mnt";
      }
    }
    return filename;
  }

  /**
   * 专为Android4.4设计的从Uri获取文件绝对路径，以前的方法已不好使
   */
  @SuppressLint("NewApi") public static String getPath(final Context context, final Uri uri) {

    final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

    // DocumentProvider
    if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
      // ExternalStorageProvider
      if (isExternalStorageDocument(uri)) {
        final String docId = DocumentsContract.getDocumentId(uri);
        final String[] split = docId.split(":");
        final String type = split[0];

        if ("primary".equalsIgnoreCase(type)) {
          return Environment.getExternalStorageDirectory() + "/" + split[1];
        }

        // handle non-primary volumes
      }
      // DownloadsProvider
      else if (isDownloadsDocument(uri)) {

        final String id = DocumentsContract.getDocumentId(uri);
        final Uri contentUri =
            ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),
                Long.valueOf(id));

        return getDataColumn(context, contentUri, null, null);
      }
      // MediaProvider
      else if (isMediaDocument(uri)) {
        final String docId = DocumentsContract.getDocumentId(uri);
        final String[] split = docId.split(":");
        final String type = split[0];

        Uri contentUri = null;
        if ("image".equals(type)) {
          contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
        } else if ("video".equals(type)) {
          contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
        } else if ("audio".equals(type)) {
          contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
        }

        final String selection = "_id=?";
        final String[] selectionArgs = new String[] { split[1] };

        return getDataColumn(context, contentUri, selection, selectionArgs);
      }
    }
    // MediaStore (and general)
    else if ("content".equalsIgnoreCase(uri.getScheme())) {
      return getDataColumn(context, uri, null, null);
    }
    // File
    else if ("file".equalsIgnoreCase(uri.getScheme())) {
      return uri.getPath();
    }

    return null;
  }

  /**
   * Get the value of the data column for this Uri. This is useful for
   * MediaStore Uris, and other file-based ContentProviders.
   *
   * @param context The context.
   * @param uri The Uri to query.
   * @param selection (Optional) Filter used in the query.
   * @param selectionArgs (Optional) Selection arguments used in the query.
   * @return The value of the _data column, which is typically a file path.
   */
  public static String getDataColumn(Context context, Uri uri, String selection,
      String[] selectionArgs) {

    Cursor cursor = null;
    final String column = "_data";
    final String[] projection = { column };

    try {
      cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
      if (cursor != null && cursor.moveToFirst()) {
        final int column_index = cursor.getColumnIndexOrThrow(column);
        return cursor.getString(column_index);
      }
    } finally {
      if (cursor != null) cursor.close();
    }
    return null;
  }

  /**
   * @param uri The Uri to check.
   * @return Whether the Uri authority is ExternalStorageProvider.
   */
  public static boolean isExternalStorageDocument(Uri uri) {
    return "com.android.externalstorage.documents".equals(uri.getAuthority());
  }

  /**
   * @param uri The Uri to check.
   * @return Whether the Uri authority is DownloadsProvider.
   */
  public static boolean isDownloadsDocument(Uri uri) {
    return "com.android.providers.downloads.documents".equals(uri.getAuthority());
  }

  /**
   * @param uri The Uri to check.
   * @return Whether the Uri authority is MediaProvider.
   */
  public static boolean isMediaDocument(Uri uri) {
    return "com.android.providers.media.documents".equals(uri.getAuthority());
  }

  public static void openFile(File file, Context context) {

    // 这里最好try一下，有可能会报错。比如说你的MIME类型是打开邮箱，但是你手机里面没装邮箱客户端，就会报错。
    try {
      context = context.getApplicationContext();
      Intent intent = getFileIntent(file);
      context.startActivity(intent);
    } catch (Exception e) {

      e.printStackTrace();
      ToastUtil.show(MyStringUtil.connect(R.string.openFile, R.string.failure));
    }
  }

  public static Intent getFileIntent(File file) {
    Intent intent = new Intent();
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    intent.setAction(Intent.ACTION_VIEW);

    String type = getMIMEType(file);

    intent.setDataAndType(Uri.fromFile(file), type);
    return intent;
  }

  @SuppressLint("DefaultLocale") private static String getMIMEType(File file) {

    String type = "*/*";
    String fName = file.getName();
    // 获取后缀名前的分隔符"."在fName中的位置。
    int dotIndex = fName.lastIndexOf(".");
    if (dotIndex < 0) {
      return type;
    }
        /* 获取文件的后缀名 */
    String end = fName.substring(dotIndex, fName.length()).toLowerCase();
    if (end == "") return type;
    // 在MIME和文件类型的匹配表中找到对应的MIME类型。
    for (int i = 0; i < MIME_MapTable.length; i++) {
      if (end.equals(MIME_MapTable[i][0])) type = MIME_MapTable[i][1];
    }
    return type;
  }

  /**
   * 根据文件路径获取文件名
   */
  public static String getFileNameByFilePath(String filePath) {
    if (filePath != null && filePath.contains("/")) {
      return filePath.substring(filePath.lastIndexOf("/") + 1, filePath.length());
    }
    if (filePath != null && filePath.contains("\\")) {
      return filePath.substring(filePath.lastIndexOf("\\") + 1, filePath.length());
    }
    return null;
  }

  /**
   * 根据图片路径获取缩略图路径
   */
  public static String getThumbNailFilePath(String filePath) {
    if (filePath == null || filePath.equals("")) {
      return null;
    }
    if (!filePath.contains(".")) return "";
    String filePrex = filePath.substring(0, filePath.lastIndexOf("."));
    filePath = filePrex + "_small" + filePath.substring(filePrex.length());
    LogUtil.i("filePathThumbNail=" + filePath);
    return filePath;
  }

  /**
   * 根据缩略图路径获取原图路径
   */
  // public static String getFilePathByThumbNailPath(String filePath){
  // if (filePath==null||filePath.equals("")) {
  // return null;
  // }
  // String filePrex =filePath.substring(0, filePath.lastIndexOf("_small"));
  // filePath = filePrex + filePath.substring(filePrex.length()+1);
  // LogUtil.i("filePath"+filePath);
  // return filePath;
  //
  //
  // }
  public static void stringToFile(String string, File file) {

    FileOutputStream outputStream;

    try {
      File path = file.getParentFile();
      if (path.isDirectory() && (!path.exists())) {
        path.mkdirs();
      }

      outputStream = new FileOutputStream(file);
      //            outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
      outputStream.write(string.getBytes());
      outputStream.close();
      LogUtil.i("文件写入成功" + file.getName());
    } catch (Exception e) {
      e.printStackTrace();
      LogUtil.e("文件写入失败" + file.getName(), e);
    }
  }

  public static boolean deleteFile(File mFileLocal) {
    if (mFileLocal != null && mFileLocal.exists()) {
      return mFileLocal.delete();
    }
    return false;
  }

  public static void md() {
    StringBuilder builder = new StringBuilder();

    File file = new File("C:/wangyanan/workspace/github/LearningNotes");
    md1(builder, file);
    FileUtil.stringToFile(builder.toString(),
        new File("C:/wangyanan/workspace/github/LearningNotes", "config.md"));
  }

  private static void md1(StringBuilder builder, File file) {
    File[] files = file.listFiles();
    int lenth = files.length;
    for (File file1 : files) {
      if (file1.isFile() && file1.getName().contains(".md")) {
        builder.append("* [" + file1.getName() + "](" + file1.getAbsolutePath() + ")\n");
      }
      if (file1.isDirectory()) {
        md1(builder, file1);
      }
    }
  }

  /**
   * Java对象保存到文件
   */
  public static boolean writeToFile(Object object, File file) {

    if (object == null || file == null) return false;
    File path = file.getParentFile();
    if (path != null && path.isDirectory() && (!path.exists())) {
      path.mkdirs();
    }
    try {
      ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(file));
      os.writeObject(object);
      os.close();
      return true;
    } catch (Exception e) {
      e.printStackTrace();
      LogUtil.e("文件保存失败", e);
      return false;
    }
  }

  /***
   * 从文件中读取Java对象
   */
  public static Object readFromFile(File file) {
    if (file == null) return null;
    try {
      ObjectInputStream is = new ObjectInputStream(new FileInputStream(file));
      return is.readObject();
    } catch (Exception e) {
      e.printStackTrace();
      LogUtil.e("读取文件失败", e);
      return null;
    }
  }

  public static File[] orderByDate(String fliePath) {
    try {
      File file = new File(fliePath);
      File[] fs = file.listFiles();
      Arrays.sort(fs, new Comparator<File>() {
        public int compare(File f1, File f2) {
          long diff = f1.lastModified() - f2.lastModified();
          if (diff > 0) {
            return -1;
          } else if (diff == 0) {
            return 0;
          } else {
            return 1;
          }
        }
      });
      return fs;
    } catch (Exception e) {
      e.printStackTrace();
      return null;
    }
  }

  /**
   * 获取文件大小
   */
  public static String readableFileSize(long size) {
    if (size <= 0) return "0";
    final String[] units = new String[] { "B", "KB", "MB", "GB", "TB" };
    int digitGroups = (int) (Math.log10(size) / Math.log10(1024));
    return new DecimalFormat("#,##0.#").format(size / Math.pow(1024, digitGroups))
        + " "
        + units[digitGroups];
  }
}
